package br.uniceub.fsw.agenda.model.dao;

import br.uniceub.fsw.agenda.exception.BusinessException;
import br.uniceub.fsw.agenda.exception.DatabaseException;
import br.uniceub.fsw.agenda.exception.UniqueConstraintException;
import br.uniceub.fsw.agenda.model.vo.TipoTelefoneVO;
import br.uniceub.fsw.agenda.model.vo.TelefoneVO;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Bruno
 */
public class TelefoneDAO extends GenericDAO {
    
    public TelefoneDAO(Connection con) {
        super(con);
    }   
    
    public List<TelefoneVO> findAll() throws BusinessException, DatabaseException {
        //montar string de consulta
        StringBuilder query = new StringBuilder();
        // TODO: Arrumar o SELECT
        query.append("SELECT *");
        query.append(" FROM TB_Telefone");
        query.append(" ORDER BY nr_telefone");
        
        //lista que vai armazenar os objetos Telefone da consulta
        List<TelefoneVO> resultado = new ArrayList<TelefoneVO>();
        
        try {
            
            //objeto con é herdado da super classe
            Statement st = con.createStatement();
            ResultSet rs = st.executeQuery(query.toString());
            while (rs.next()) {
                TelefoneVO telefone = new TelefoneVO();
                
                telefone.setNrTelefone(rs.getLong("NR_TELEFONE"));
                
                TipoTelefoneDAO tipoTelefoneDAO = new TipoTelefoneDAO(this.con);
                
                TipoTelefoneVO tipoTelefone = tipoTelefoneDAO.findById(rs.getInt("ID_TIPOTELEFONE"));
                
                telefone.setTipoTelefone(tipoTelefone);
                
                resultado.add(telefone);
            }
            
            st.close();
            rs.close();
            
            return resultado;            
        } catch (SQLException ex) {
            ex.printStackTrace();
            throw new DatabaseException("Erro ao buscar Telefones", ex);
        }        
    }

    public TelefoneVO findById(Integer idTelefone) throws BusinessException, DatabaseException {
        //montar string de consulta
        StringBuilder query = new StringBuilder();
        // TODO: Arrumar o SELECT
        query.append("SELECT * ");
        query.append("FROM TB_TELEFONE ");
        query.append("WHERE ID_TELEFONE = ?");
        
        TelefoneVO telefone = new TelefoneVO();
        
        try {
            
            //objeto con é herdado da super classe
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, idTelefone.toString());
            
            ResultSet rs = st.executeQuery();
            while (rs.next()) {
                
                telefone.setIdTelefone(idTelefone);
                telefone.setNrTelefone(rs.getLong("NR_TELEFONE"));

                TipoTelefoneDAO tipoTelefoneDAO = new TipoTelefoneDAO(this.con);
                
                TipoTelefoneVO tipoTelefone = tipoTelefoneDAO.findById(rs.getInt("ID_TIPOTELEFONE"));
                
                telefone.setTipoTelefone(tipoTelefone);
            }
            
            st.close();
            rs.close();
            
            return telefone;            
        } catch (SQLException ex) {
            ex.printStackTrace();
            throw new DatabaseException("Erro ao buscar Telefone", ex);
        }        
    }

    public TelefoneVO findByNumero(Long nrTelefone) throws BusinessException, DatabaseException {
        //montar string de consulta
        StringBuilder query = new StringBuilder();
        // TODO: Arrumar o SELECT
        query.append("SELECT * ");
        query.append("FROM TB_TELEFONE ");
        query.append("WHERE NR_TELEFONE = ?");
        
        TelefoneVO telefone = new TelefoneVO();
        
        try {
            
            //objeto con é herdado da super classe
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, nrTelefone.toString());
            
            ResultSet rs = st.executeQuery();
            while (rs.next()) {
                
                telefone.setIdTelefone(rs.getInt("ID_TELEFONE"));
                telefone.setNrTelefone(nrTelefone);

                TipoTelefoneDAO tipoTelefoneDAO = new TipoTelefoneDAO(this.con);
                
                TipoTelefoneVO tipoTelefone = tipoTelefoneDAO.findById(rs.getInt("ID_TIPOTELEFONE"));
                
                telefone.setTipoTelefone(tipoTelefone);
            }
            
            st.close();
            rs.close();
            
            return telefone;            
        } catch (SQLException ex) {
            ex.printStackTrace();
            throw new DatabaseException("Erro ao buscar Telefone", ex);
        }        
    }

    /**
     * Faz o insert de um novo telefone e devolve a o id recem gerado
     * @param Telefone telefone que se deseja inserir
     * @return ID auto-increment gerado para esse registro
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public Integer insert(TelefoneVO telefone) throws BusinessException, DatabaseException {        
        StringBuilder query = new StringBuilder();
        query.append("INSERT INTO TB_TELEFONE(NR_TELEFONE, ID_TIPOTELEFONE) ");
        query.append("VALUES (?,?)");
        
        //retornar id gerado
        Integer generatedId = null;
        
        try {           
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, telefone.getNrTelefone().toString());
            st.setString(2, telefone.getTipoTelefone().getIdTipoTelefone().toString());
            
            st.executeUpdate();
            
            //pegar id gerado
            ResultSet rs = st.getGeneratedKeys();
            while (rs.next()) {
                generatedId = new Integer(rs.getString(1));                
            }                    
            
            return generatedId;            
        } catch (SQLException ex) {            
            ex.printStackTrace();
            if (ex.getErrorCode() == 1062) {
                throw new UniqueConstraintException(ex.getMessage(), ex);                
            }
            throw new DatabaseException("Erro no DAOTelefone.insert()", ex);            
        }      
    }
    
    /**
     * Faz o update de uma telefone
     * @param Telefone telefone que se deseja alterar
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public void update(TelefoneVO telefone) throws BusinessException, DatabaseException {        
        StringBuilder query = new StringBuilder();
        query.append("UPDATE TB_TELEFONE SET NR_TELEFONE = ?, ID_TIPOTELEFONE = ? ");
        query.append("WHERE ID_TELEFONE = ?");
        
        try {           
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, telefone.getNrTelefone().toString());
            st.setString(2, telefone.getTipoTelefone().getIdTipoTelefone().toString());
            st.setString(3, telefone.getIdTelefone().toString());
            
            st.executeUpdate();
        } catch (SQLException ex) {            
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOTelefone.update()", ex);
        }      
    }
    
    /**
     * Faz o delete de um telefone
     * @param Telefone telefone que se deseja excluir
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public void delete(TelefoneVO telefone) throws BusinessException, DatabaseException {        
        StringBuilder query = new StringBuilder();
        query.append("DELETE FROM TB_TELEFONE ");
        query.append("WHERE ID_TELEFONE = ?");
        
        try {           
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, telefone.getIdTelefone().toString());
            
            st.executeUpdate();
        } catch (SQLException ex) {            
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOTelefone.delete()", ex);            
        }      
    }

}
